#include "mylib.h"

#if HAVE_QUEUE_H

PS_QUEUE QueueInit(const char *pcName, size_t size)
{
	PS_QUEUE pst;
	pst = Malloc(sizeof(S_QUEUE));
	pst->inPtr = pst->outPtr = pst->ctr = 0;
	Pthread_mutex_init(&pst->mutex, NULL);
	Pthread_cond_init(&pst->cond, NULL);
	strncpy(pst->queue_name, pcName, sizeof(pst->queue_name));
	pst->bufptr = (void **)Malloc(size*sizeof(void *));
	pst->size = size;
	return pst;
}

void *QueueGetTime(PS_QUEUE psQueue, int s)
{
	void *ptr;
	struct timespec to;
	Pthread_mutex_lock(&psQueue->mutex);
	while(psQueue->ctr == 0)
	{
		to.tv_sec = time(NULL)+s;
		to.tv_nsec = 0;
		if (Pthread_cond_timedwait(&psQueue->cond, &psQueue->mutex, &to) != 0)
		{
			Pthread_mutex_unlock(&psQueue->mutex);
			return NULL;
		}
	}
	ptr = psQueue->bufptr[psQueue->outPtr++];
	psQueue->ctr--;
	psQueue->outPtr %= psQueue->size;
	Pthread_mutex_unlock(&psQueue->mutex);
	return ptr;
}

void *QueueGet(PS_QUEUE psQueue)
{
	void *ptr;
	Pthread_mutex_lock(&psQueue->mutex);
	while(psQueue->ctr == 0)
	{
		Pthread_cond_wait(&psQueue->cond, &psQueue->mutex);
	}
	ptr = psQueue->bufptr[psQueue->outPtr++];
	psQueue->ctr--;
	psQueue->outPtr %= psQueue->size;
	Pthread_mutex_unlock(&psQueue->mutex);
	return ptr;
}

void QueuePut(PS_QUEUE psQueue, void *ptr)
{

	Pthread_mutex_lock(&psQueue->mutex);
	if (psQueue->ctr < psQueue->size)
	{
		psQueue->bufptr[psQueue->inPtr++] = ptr;
		psQueue->ctr++;
		psQueue->inPtr %= psQueue->size;
	}
	else
	{
		err_msg("queue:%s the buff is full", psQueue->queue_name);
	}
	Pthread_cond_signal(&psQueue->cond);
	Pthread_mutex_unlock(&psQueue->mutex);
}

void QueueDel(PS_QUEUE psQueue)
{
	Pthread_cond_broadcast(&psQueue->cond);
	pthread_cond_destroy(&psQueue->cond);
	Pthread_mutex_destroy(&psQueue->mutex);
	free(psQueue->bufptr);
	free(psQueue);
}

#endif